package main

import (
	"crypto/dsa"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
)

func GenRSAPriv(fileName, passwd string, len int) error {
priv, err := rsa.GenerateKey(rand.Reader, len)
if err != nil {
return err
}

data := x509.MarshalPKCS1PrivateKey(priv)
err = encodePrivPemFile(fileName, passwd, data)
return err
}

//GenECDSAPriv 生成ECDSA私钥文件
func GenECDSAPriv(fileName, passwd string) error {
priv, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
if err != nil {
return err
}
data, err := x509.MarshalECPrivateKey(priv)
if err != nil {
return err
}
err = encodePrivPemFile(fileName, passwd, data)
return err
}
//GenDSAPriv 生成DSA私钥(用于演示)
func GenDSAPriv() {
priv := &dsa.PrivateKey{}
dsa.GenerateParameters(&priv.Parameters, rand.Reader, dsa.L1024N160)
dsa.GenerateKey(priv, rand.Reader)
fmt.Printf("priv:%+v\n", priv)
}

//DecodePriv 解析私钥文件生成私钥，（RSA，和ECDSA两种私钥格式）
func DecodePriv(fileName, passwd string) (pubkey, priv interface{}, err error) {
data, err := ioutil.ReadFile(fileName)
if err != nil {
return nil, nil, errors.New("读取私钥文件错误")
}
block, _ := pem.Decode(data)
data, err = x509.DecryptPEMBlock(block, []byte(passwd))
if err != nil {
return nil, nil, err
}

privKey, err := x509.ParsePKCS1PrivateKey(data) //解析成RSA私钥
if err != nil {
priv, err = x509.ParseECPrivateKey(data) //解析成ECDSA私钥
if err != nil {
return nil, nil, errors.New("支持持RSA和ECDSA格式的私钥")
}
}
priv = privKey
pubkey = &privKey.PublicKey
return
}

//生成私钥的pem文件
func encodePrivPemFile(fileName, passwd string, data []byte) error {
block, err := x509.EncryptPEMBlock(rand.Reader, "RSA PRIVATE KEY", data, []byte(passwd), x509.PEMCipher3DES)
if err != nil {
return err
}
file, err := os.Create(fileName)
if err != nil {
return err
}
err = pem.Encode(file, block)
if err != nil {
return err
}
return nil
}